package com.rshang.rsdp.service.impl;

import com.google.common.base.Joiner;
import com.rshang.rsdp.annotation.Log;
import com.rshang.rsdp.bean.DataGrid;
import com.rshang.rsdp.bean.Response;
import com.rshang.rsdp.common.status.ExcelStatusCode;
import com.rshang.rsdp.common.status.StatusCode;
import com.rshang.rsdp.common.status.ZhStatusCode;
import com.rshang.rsdp.entity.DmRsdlZhxx;
import com.rshang.rsdp.exception.RsdpSystemException;
import com.rshang.rsdp.kit.StrKits;
import com.rshang.rsdp.mapper.DmRsdlZhxxMapper;
import com.rshang.rsdp.service.IDmRsdlZhxxService;
import com.rshang.rsdp.service.IExcelService;
import com.rshang.rsdp.util.excel.CellKey;
import com.rshang.rsdp.util.i18n.I18nMessage;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import org.apache.ibatis.annotations.Param;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 * 账号代码信息表 服务实现类
 * </p>
 *
 * @author zhangjun
 * @since 2017-08-20
 */
@Service
public class DmRsdlZhxxServiceImpl extends ServiceImpl<DmRsdlZhxxMapper, DmRsdlZhxx> implements IDmRsdlZhxxService {

    private static final Logger logger = LoggerFactory.getLogger(DmRsdlZhxxServiceImpl.class);

    @Autowired
    I18nMessage i18n;

    @Autowired
    IExcelService excel;

    private static final List<CellKey> COLUMN_IMPORT = new ArrayList<CellKey>() {{
        add(new CellKey("账户类型", "1", true));//1字符型 2数字型 3日期型 4日期时间 9其他
        add(new CellKey("账户名称", "1", 100, true));
        add(new CellKey("账号", "1", 50, true));
    }};

    @Override
    public DataGrid getManagePageList(Page<HashMap> page, HttpServletRequest request) {
        String zhlx = StrKits.emptyToStr(request.getParameter("zhlx"));
        String zhmc = StrKits.emptyToStr(request.getParameter("zhmc"));
        String zhbh = StrKits.emptyToStr(request.getParameter("zhbh"));

        page.setRecords(this.baseMapper.getZhList(page, zhlx, zhmc, zhbh));
        return new DataGrid(page.getRecords(), page.getTotal());
    }

    @Log(module = "账户列表", desc = "新建账户")
    @Override
    public Response addSave(HttpServletRequest request, String czr) {
        if (this.baseMapper.selectCount(Condition.create().setSqlSelect("ZH_ID")
                .eq("ZH_BH", StrKits.emptyToStr(request.getParameter("zhbh")))) > 0) {
            throw new RsdpSystemException(ZhStatusCode.ZH_FOUND.getCode(), i18n.getMessage(ZhStatusCode.ZH_FOUND.getKey()));
        } else {
            DmRsdlZhxx zh = new DmRsdlZhxx();
            zh.setZhId(StrKits.uuid());
            zh.setZhType(StrKits.emptyToStr(request.getParameter("sel_zhlx")));
            zh.setZhMc(StrKits.emptyToStr(request.getParameter("zhmc")));
            zh.setZhBh(StrKits.emptyToStr(request.getParameter("zhbh")));
            zh.setLrr(czr);
            zh.setXgr(czr);
            zh.setYxBz(StrKits.emptyToStr(request.getParameter("sel_yxbz")));
            zh.setXyBz(StrKits.emptyToStr(request.getParameter("sel_xybz")));
            if (this.baseMapper.insert(zh) > 0) {
                return new Response(StatusCode.SUCCESS.getCode(), i18n.getMessage(StatusCode.SUCCESS.getKey()));
            } else {
                return new Response(StatusCode.OPER_FAILED.getCode(), i18n.getMessage(StatusCode.OPER_FAILED.getKey()));
            }
        }
    }

    @Override
    public DmRsdlZhxx get(HttpServletRequest request) {
        DmRsdlZhxx result = this.selectById(StrKits.emptyToStr(request.getParameter("id")));
        if (result == null) {
            throw new RsdpSystemException(ZhStatusCode.ZH_NOTFOUND.getCode(), i18n.getMessage(ZhStatusCode.ZH_NOTFOUND.getKey()));
        } else {
            return result;
        }
    }

    @Log(module = "账户列表", desc = "账户编辑")
    @Override
    public Response editSave(HttpServletRequest request, String czr) {
        String id = StrKits.emptyToStr(request.getParameter("hid_id"));
        Wrapper wrapper = Condition.create().setSqlSelect("ZH_ID")
                .eq("ZH_BH", StrKits.emptyToStr(request.getParameter("zhbh")))
                .ne("ZH_ID", id);

        if (this.baseMapper.selectCount(wrapper) > 0) {
            throw new RsdpSystemException(ZhStatusCode.ZH_FOUND.getCode(), i18n.getMessage(ZhStatusCode.ZH_FOUND.getKey()));
        } else {
            DmRsdlZhxx zh = new DmRsdlZhxx();
            zh.setZhId(StrKits.emptyToStr(request.getParameter("hid_id")));
            zh.setZhMc(StrKits.emptyToStr(request.getParameter("zhmc")));
            zh.setZhType(StrKits.emptyToStr(request.getParameter("sel_zhlx")));
            zh.setZhBh(StrKits.emptyToStr(request.getParameter("zhbh")));
            zh.setXgr(czr);
            zh.setXgsj(new Date());
            zh.setYxBz(StrKits.emptyToStr(request.getParameter("sel_yxbz")));
            zh.setXyBz(StrKits.emptyToStr(request.getParameter("sel_xybz")));
            if (this.baseMapper.updateById(zh) > 0) {
                return new Response(StatusCode.SUCCESS.getCode(), i18n.getMessage(StatusCode.SUCCESS.getKey()));
            } else {
                return new Response(StatusCode.OPER_FAILED.getCode(), i18n.getMessage(StatusCode.OPER_FAILED.getKey()));
            }
        }
    }

    @Log(module = "账户列表", desc = "账户删除")
    @Override
    public Response deleteSave(HttpServletRequest request, String czr) {
        DmRsdlZhxx result = this.baseMapper.selectById(StrKits.emptyToStr(request.getParameter("id")));
        if (result == null)//数据字典不存在
        {
            throw new RsdpSystemException(ZhStatusCode.ZH_NOTFOUND.getCode(), i18n.getMessage(ZhStatusCode.ZH_NOTFOUND.getKey()));
        } else        //物理删除
        {
            if (this.baseMapper.deleteById(result) > 0) {
                return new Response(StatusCode.SUCCESS.getCode(), i18n.getMessage(StatusCode.SUCCESS.getKey()));
            } else {
                return new Response(StatusCode.OPER_FAILED.getCode(), i18n.getMessage(StatusCode.OPER_FAILED.getKey()));
            }

        }
    }

    @Override
    public Response checkZhbh(HttpServletRequest request) {
        String id = StrKits.emptyToStr(request.getParameter("id"));
        Wrapper wrapper = Condition.create().setSqlSelect("ZH_ID")
                .eq("ZH_BH", StrKits.emptyToStr(request.getParameter("bh")));

        if (!"".equals(id)) {
            wrapper = wrapper.ne("ZH_ID", id);
        }

        if (this.baseMapper.selectCount(wrapper) > 0) {
            throw new RsdpSystemException(ZhStatusCode.ZH_FOUND.getCode(), i18n.getMessage(ZhStatusCode.ZH_FOUND.getKey()));
        }
        return new Response(StatusCode.SUCCESS.getCode(), i18n.getMessage(StatusCode.SUCCESS.getKey()));
    }

    @Override
    public List<HashMap> getZhListByType(String zhlx) {
        return this.baseMapper.getZhListByType(zhlx);
    }

    @Override
    @Transactional
    @Log(module = "账户列表", desc = "模板导入")
    public Response importSave(MultipartFile file, String czr) {
        if (file == null)//文件为空
        {
            throw new RsdpSystemException(ExcelStatusCode.XLS_EMPTY.getCode(), i18n.getMessage(ExcelStatusCode.XLS_EMPTY.getKey()));
        }
        InputStream is = null;
        Workbook wb = null;
        Sheet sheet = null;
        Row row = null;
        Cell cell0 = null;
        Cell cell1 = null;
        Cell cell2 = null;
        List<Row> data = new ArrayList<Row>();
        List<String> errList = new ArrayList<String>();
        try {
            is = file.getInputStream();
            wb = new HSSFWorkbook(is);

            if (wb.getNumberOfSheets() == 0)//模板必须要有一个sheet表
            {
                throw new RsdpSystemException(ExcelStatusCode.XLS_NOTFORMATED.getCode(), i18n.getMessage(ExcelStatusCode.XLS_NOTFORMATED.getKey()));
            }
            //读取excel文件
            sheet = wb.getSheetAt(0);//读取第一个sheet表
            int rowCount = sheet.getPhysicalNumberOfRows();//获取模板总数
            logger.debug("zhxx importSave row count:{}", rowCount);
            if (rowCount < 2)//空数据
            {
                throw new RsdpSystemException(ExcelStatusCode.XLS_DATAEMPTY.getCode(), i18n.getMessage(ExcelStatusCode.XLS_DATAEMPTY.getKey()));
            }
            //循环读取数据
            Iterator<Row> it = sheet.iterator();
            int rowNo = 0;
            CellKey cellKey;

            //循环读取数据
            while (it.hasNext()) {
                row = it.next();
                if (row != null && row.getRowNum() > 0) {
                    rowNo = row.getRowNum();
                    //logger.debug("xgs importSave row:{}-{}-{}",cell0,cell1,cell2);
                    //模板校验
                    for (int i = 0; i < 3; i++) {
                        excel.setStringCell(row.getCell(i));
                        cellKey = COLUMN_IMPORT.get(i);
                        excel.checkCellValue(rowNo, i, cellKey, row.getCell(i), errList);
                        if (i == 0) {//判断账户类型
                            if (excel.isCellNotEmpty(row.getCell(i)) && (!"公积金账户".equals(excel.getCellValue(row.getCell(i))) && !"社保账户".equals(excel.getCellValue(row.getCell(i))))) {
                                errList.add(i18n.getMessage(ExcelStatusCode.XLS_STRFORMAT.getKey(), new Object[]{rowNo, i + 1, cellKey.getHead()}));
                            }
                        }

                        if (errList.size() > 0) {
                            if (!data.isEmpty()) {
                                data.clear();
                            }
                        } else {
                            data.add(row);
                        }
                    }
                }
            }
        } catch (IOException e) {
            logger.error("xgs importSave error:{}", e.getMessage());
            throw new RsdpSystemException(StatusCode.SERVER_ERROR.getCode(), e.getMessage());
        } finally {
            try {
                //关闭流及文件
                wb.close();
                is.close();
            } catch (IOException e) {
                logger.error("xgs importSave close error:{}", e.getMessage());
            }
        }

        if (errList.size() > 0)//模板校验错误直接抛出
        {
            return new Response(ExcelStatusCode.XLS_ERROR.getCode(), i18n.getMessage(ExcelStatusCode.XLS_ERROR.getKey(), new Object[]{Joiner.on("").join(errList)}));
        } else {
            String plId = StrKits.uuid();
            Map zhMap = new HashMap();
            String zhType;
            DmRsdlZhxx zh = null;
            //获取全部账户信息
            List<DmRsdlZhxx> zhList = this.selectList(Condition.create());
            for (DmRsdlZhxx zhxx : zhList) {
                zhMap.put(zhxx.getZhType() + "-" + zhxx.getZhMc(), zhxx.getZhBh());
            }
            for (Row rt : data) {
                cell0 = rt.getCell(0);//账户类型
                cell1 = rt.getCell(1);//账户名称
                cell2 = rt.getCell(2);//账号
                zhType = this.getZhType(cell0.getStringCellValue());
                if (!zhMap.containsKey(zhType + "-" + cell1.getStringCellValue())) {
                    zh = new DmRsdlZhxx();
                    zh.setZhId(StrKits.uuid());
                    zh.setZhType(zhType);
                    zh.setZhMc(cell1.getStringCellValue());
                    zh.setZhBh(cell2.getStringCellValue());
                    zh.setLrr(czr);
                    zh.setXgr(czr);
                    zh.setYxBz("1");
                    zh.setXyBz("1");
                    zh.setPlBs(plId);
                    if (this.baseMapper.insert(zh) < 0) {
                        return new Response(StatusCode.OPER_FAILED.getCode(), i18n.getMessage(StatusCode.OPER_FAILED.getKey()));
                    }
                    zhMap.put(zh.getZhType() + "-" + zh.getZhMc(), zh.getZhBh());
                }
            }
        }
        return new Response(StatusCode.SUCCESS.getCode(), i18n.getMessage(StatusCode.SUCCESS.getKey()));
    }

    /**
     * 获取账户类型代码
     *
     * @param zhType 账户类型代码
     *
     * @return String
     */
    private String getZhType(String zhType) {
        switch (zhType) {
            case "社保账户":
                return "01";
            case "公积金账户":
                return "02";
            default:
                return "";
        }
    }
}
